from pml import PML
from pml import Objects

class Position(Objects.object.typeobject):
    EOF = PML.object.ChangeObject.PMLInteger_FromInt(-1)

    def __init__(self, filename: str = '', fp=None, index: int = 0, column: int = 0, line: int = 0,
                 theTextOfTheLine: str = ''):
        super().__init__('Position')
        self.filename = PML.object.ChangeObject.PMLString_FromStr(filename)
        self.index = PML.object.ChangeObject.PMLInteger_FromInt(index)
        self.column = PML.object.ChangeObject.PMLInteger_FromInt(column)
        self.line = PML.object.ChangeObject.PMLInteger_FromInt(line)
        self.theTextOfTheLine = PML.object.ChangeObject.PMLString_FromStr(theTextOfTheLine)
        self.fp = fp
        self.endTag = False
    def __repr__(self):
        return f'Position(file={self.filename}, line={self.line}, column={self.column})'

    def __reduce__(self):
        return Position, (self.filename, None, self.index, self.column, self.line, self.theTextOfTheLine)

    def getObject(self):
        self.methods['__init__'] = self.tp_init

        self.methods['filename'] = self.filename
        self.methods['index'] = self.index
        self.methods['column'] = self.column
        self.methods['line'] = self.line
        self.methods['theTextOfTheLine'] = self.theTextOfTheLine

        self.methods['advanceReadNextCharacter'] = self.advanceReadNextCharacter
        self.methods['copy'] = self.copy
        self.methods['getTheTextOfTheLine'] = self.getTheTextOfTheLine

        return self

    @staticmethod
    def getTheTextOfTheLine(frame, this, position):
        this.fp.seek(0)
        for i in range(this.line.obj.value):
            text = this.fp.readline()
        this.theTextOfTheLine = PML.object.ChangeObject.PMLString_FromStr(text)

    @staticmethod
    def advanceReadNextCharacter(frame, this: 'Position', position):
        this.index.obj.value += 1
        this.column.obj.value += 1
        this.fp.seek(0, 2)
        end = this.fp.tell()
        this.fp.seek(this.index.obj.value)
        now = this.fp.tell()
        if now > end:
            this.fp.close()
            return this.EOF
        else:
            char = this.fp.read(1)
            if this.endTag:
                this.line.obj.value += 1
                this.column.obj.value = 1
                this.getTheTextOfTheLine(frame, this, position=None)
                this.endTag = False
            if char == '\n':
                this.endTag = True
            return PML.object.ChangeObject.PMLString_FromStr(char)

    @staticmethod
    def copy(frame, this: 'Position', position):
        return Objects.object.PMTypeObject(
            Position(this.filename.obj.value, this.fp, this.index.obj.value, this.column.obj.value, this.line.obj.value,
                     this.theTextOfTheLine.obj.value).getObject())

    @staticmethod
    def tp_init(frame, this, value, position):
        pass
